package com.ass.zookeeper.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.IZkStateListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.Watcher;

import java.util.List;
import java.util.function.Consumer;

public class ZkUtils {



    //监听节点信息
    public static void subscribeNode(ZkClient zkClient,String path){
        //监听
        zkClient.subscribeDataChanges(path, new IZkDataListener() {
            //修改监听
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
                System.out.println("修改的:"+s+"修改后的"+o);
            }

            //删除监听
            @Override
            public void handleDataDeleted(String s) throws Exception {
                System.out.println("删除的:"+s);
            }
        });
    }

    //监听父节点下所有的子节点
    public static void subscribeParentNodes(ZkClient zkClient, String path, Consumer<List<String>> then){
        //监听父节点下的所有子节点
        zkClient.subscribeChildChanges(path, new IZkChildListener() {
            @Override
            public void handleChildChange(String s, List<String> updateChildPathList) throws Exception {
                System.out.println("节点变动  " + s + ": " + updateChildPathList);
                if(then!=null){
                    then.accept(updateChildPathList);
                }
            }
        });
    }

    //监听客户端状态
    public static void subscribeClientStatus(ZkClient zkClient,String path) {
        zkClient.subscribeStateChanges(new IZkStateListener() {
            @Override
            public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
                if(state== Watcher.Event.KeeperState.SyncConnected){
                    //当我重新启动后start，监听触发
                    System.out.println("连接成功");
                }else if(state== Watcher.Event.KeeperState.Disconnected){
                    System.out.println("连接断开");//当我在服务端将zk服务stop时，监听触发
                }else
                    System.out.println("其他状态"+state);
            }

            @Override
            public void handleNewSession() throws Exception {
                System.out.println("重建session");

            }

            @Override
            public void handleSessionEstablishmentError(Throwable error) throws Exception {

            }
        });
    }



    //创建一个节点
    //CreateMode 配置节点的属性
    public static void createPersistent(ZkClient zkClient, String path, String json, CreateMode createMode){
        zkClient.create(path,json,createMode);
    }

    //读取节点列表
    public static List<String> childrenList(ZkClient zkClient,String path){
        List<String> children = zkClient.getChildren(path);
        return children;
    }

    public static void writeData(ZkClient zkClient,String path,String data){
        zkClient.writeData(path,data);
    }
    //读取节点下的数据 映射出对应类型 解决泛型擦除
    public  static <M> M getPathData(ZkClient zkClient, String path, TypeReference<M> typeReference){
        return JSON.parseObject(zkClient.readData(path), typeReference);
    }
    //判断节点是否存在
    public static boolean exists(ZkClient zkClient,String path){
        return zkClient.exists(path);
    }

}
